\chapter{Rotation d'un \texttt{QCM} incliné}

Pour cette section, il y a deux principales classes java qui gèrent la rotation, la classe \verb+ImagePanel+ et la classe \verb+Orienter+. Cependant \verb+ImagePanel+ est la classe la plus importante car elle contient une méthode \verb+rotate+ qui effectue réellement la rotation. Elle a deux constructeurs, le premier prend en paramètre toutes les informations concernant les dimensions et les coordonnées du coin supérieur gauche de l'image, tandis que le second fait appel au premier par l'intermédiaire du mot clé java this(). En effet le second utilise l'api java pour récupérer les dimensions de l'image, de ce fait l'utilisateur pourra passer en paramètre le nom de l'image à traiter .

\section{Rotation}
Pour réaliser la rotation, nous avons effectué une transformation affine sur l'image, nous utilisons les mêmes que celles de \textit{Graphics2D}.
Les transformations possibles avec Graphics2D sont représentées par des instances de la classe \verb+AffineTransform:+ 
\begin{itemize}
 \item Transformations euclidiennes : conservent les distances et les angles 
 \item translation:static AffineTransform getTranslateInstance(double tx, double ty)
 \item rotation:static AffineTransform getRotateInstance(double theta):rotation theta autour de l'origine et static AffineTransform getRotateInstance(double theta, double x, double y):rotation de theta autour du point x, y. L'angle est exprimé en radians.\\ 
 \end{itemize}
 La combinaison des différentes transformations créées une matrice (3×3) telles que les nouvelles coordonnées x' et y' sont obtenues à partir des anciennes x et y de la façon suivante.

 $$
 \begin{pmatrix}
 x'\\
 y' \\
 1
  \end{pmatrix} =\begin{pmatrix}
 a & b & c\\
 d & e & f\\
 0 & 0 & 1
  \end{pmatrix}*\begin{pmatrix} x \\ y\\ 1  \end{pmatrix}
$$


La transformation affine de la rotation est représentée par la matrice:

 $$ \begin{pmatrix}
 x'\\
 y' \\
 1
  \end{pmatrix} =\begin{pmatrix}
 cons(\theta) & -sin(\theta)  & 0\\
 sin(\theta) & cos(\theta) & f\\
 0 & 0 & 1
  \end{pmatrix}*\begin{pmatrix} x \\ y\\ 1  \end{pmatrix}
$$

 Cependant, avant d'effectuer la réorientation nous vérifions que l'image est bien inclinée pour éviter de faire une rotation inutile. Pour cela nous avons besoin que les coordonnées des centres des deux premiers cercles pour ensuite pouvoir calculer l'angle d'inclinaison. Le calcul de l'angle d'inclinaison se fait à l'aide de la formule mathématique arctan.\\\\

 \subsection{BufferedImage}
  La classe BufferedImage est dérivée de Image.

 Une BufferedImage est composée :
 \begin{itemize}
 \item d’un ColorModel qui définit la façon d’interpréter les couleurs. Exemple:
 TYPE\_INT\_ARGB  :alpha, rouge, vert, bleu sur 8 bits, dans un int
 TYPE\_INT\_RGB   : rouge, vert, bleu sur 8 bits chacun, dans un int
 TYPE\_BYTE\_GRAY  :1 octet par pixel, niveau de gris
 \item d’un WritableRaster, un Raster autorisé en écriture
 \end{itemize}


 \begin{figure}[H]
   \centering
   \includegraphics[width=10cm,height=7cm]{../images/image.png}
   \caption{Diagramme de classe}
     \label{dia}
 \end{figure}

 \begin{figure}[H]
   \centering
   \includegraphics[width=10cm,height=7cm]{../images/image1.png}
   \caption{Structure de la classe BuffereImaged}
     \label{Structure}
 \end{figure}

 Un Raster est composé:
 \begin{itemize}
 \item d’un DataBuffer contenant les données brutes, dans un tableau. 
 \item d’un SampleModel (modèle d’échantillonage) qui interprète les données brutes. 
 \end{itemize} 
 On obtient le modèle et le raster par les méthodes get. 
 WritableRaster raster = image.getRaster();
 ColorModel model = image.getColorModel();\\
 C'est cette méthode getRaster qui a été utilisée pour récupérer les pixels de l'image pour ensuite détecter les pixels lumineux et ainsi déterminer les coordonnées des centres des cercles.  
 L'affichage de nos images s'effectue par la méthode drawImage de la classe \textsf{Graphics2D}.

 \subsection{Lecture/Ecriture d'image}
 La classe ImageIO permet de lire et d'écrire des images à partir de fichiers. Les formats d'images sont BMP, PNG, JPEG, et GIF en lecture seulement. 
 Lecture
 BufferedImage bimg;

 \ldots

 File f = new File("\ldots");

 try {
    bimg = ImageIO.read(f);
 }catch (IOException e) {
    ...
 }


 Ecriture

 BufferedImage bimg;
 ...
 File f = new File("...");
 try {
    if(!ImageIO.write(bimg, "png", f))
      JOptionPane.showMessageDialog(null, "Ecriture impossible : "+format);
 }catch (IOException e) { 
    ...
 }
 Les formats d'images en lecture ou en écriture qui sont utilisés par read et write, peuvent être obtenus par:
 \begin{itemize} 
 \item String[] ImageIO.getReaderFormatNames() 
 \item String[] ImageIO.getWriterFormatNames() 

 \end{itemize}
 \subsection{Morphologie mathématique}
 Pour détecter les formes en l'occurrence des cercles sur une image, nous avons utilisé quelques opérateurs de la morphologie mathématique.Ces opérateurs doivent s'appliquer sur une image binaire. Les images binaires sont des images pour lesquelles chaque pixel ne peut prendre que deux valeurs: zéro ou un. Ce contexte simple permettra une formalisation mathématique des problèmes. L'image binaire est obtenue à partir d'une image en niveaux de gris, au moyen d'une technique de seuillage. Ainsi l'image binaire renfermera un certain nombre de régions (ensemble de pixels connexes) codées à 1, que l'on peut définir comme des objets d'intérêt, par rapport à un fond codé à 0. Cependant, une transformation morphologique utilise un ensemble particulier de centre x, de géométrie et de taille connues, appelé élément structurant.\\ 
 L'élément structurant se déplace de façon à ce que son centre passe successivement par toutes les positions possibles dans l'image binaire.

 \section{Transformation Morphologique}
 Pour chacune des positions du centre de l'élément structurant, on se pose une question relativement à l'union ou à l'intersection de l'élément structurant avec les objets de l'image. L'ensemble des points correspondant à une réponse positive permet de construire une nouvelle image résultat.\\
 Ainsi, pour la détection des cercles nous avons utilisé principalement deux opérateurs morphologiques : La dilatation et l'érosion.\\
 Pour la dilatation, la question posée est: l'intersection entre l'élément structurant et la région de l'image est-elle non vide?\\
 Pour l'érosion, la question posée est: l'élément structurant est-il complérement inclus dans la région de l'image?\\
 Remarque: Notre élément structurant est un cercle car il s'agit de retrouver des cercles dans une image.

 \section{Erosion}
 Si l'élément structurant B déplacé au point x est inclus dans un objet de l'image le point x est conservé dans la transformée. Les objets de taille inférieure à celle de l'élément structurant disparaissent de l'image résultat. S'il existe des trous dans les objets, c'est à dire des morceaux de fond à l'intérieur des objets, ils sont accentués. Une érosion avec élément structurant de taille importante peut souvent se réaliser en répétant plusieurs fois une érosion avec un élément structurant de taille plus faible. La forme des objets dans l'image résultat dépend fortement de celle de l'élément structurant. 

 \section{Dilatation}
 Si l'élément structurant B déplacé au point x touche au moins un objet de l'image, le point x est conservé dans la transformée.
 \\
 La dilatation est l'opération duale (ou inverse) de l'érosion: elle consiste à éroder le complémentaire de l'image, puis à complémenter le résultat. Tous les objets <<grossissent>> d'une partie correspondant à la taille de l'élément structurant. S'il existe des <<trous>> dans les objets, c'est$-$à$-$dire 
des morceaux de fond à l'intérieur des objets, ils peuvent être comblés.
Si des objets sont situés à une distance moins grande que la taille de l'élément structurant, il peuvent fusionner. 
Une dilatation avec un élément structurant de taille importante peut souvent se réaliser en répétant plusieurs fois une dilatation avec un élément structurant de taille plus faible. 



